<?php


namespace app\common\cachemodel\zl1_relation;


use app\common\cachemodel\Goods;
use app\common\cachemodel\Recode;
use app\common\lib\Util;
use app\common\model\BaseCache;
use think\Env;
use think\Exception;
use think\Log;
use XznsTools\cache\CacheManage;

class Zl1RelationAnalysisReport extends BaseCache
{
    protected $table = 'wechat_backup_07_18_14_43_00.zl1_relation_analysis_report';

    protected $cacheModel = 'relation_analysis.report';

    /**
     * 删除用户 关系研究所报告 数据
     * @param int $id
     * @param int $uid
     * @param int $type
     * @param int $rid1
     * @param int $rid2
     * @return bool
     * @throws \Exception
     */
    public function DeleteData(int $id, int $uid, int $type, int $rid1, int $rid2)
    {
        try
        {
            $this->where(['id' => $id])->update(['is_del' => 1, 'delete_time' => time()]);
        }
        catch (\Exception $e)
        {
            Log::write("ID【{$id}】删除 关系研究所报告 Zl1RelationAnalysisReport 数据失败：" . $e->getMessage() . '[ ' . $e->getFile() . '：' . $e->getLine() . ' ]', 'error', true);
            return false;
        }
        // 删除 详情
        $key = "{$uid}:{$rid1}:{$rid2}:{$type}";
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $key)->rmCache();
        // 删除列表详情
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $id)->rmCache();
        // 列表删除
        $this->listDataDel($uid, [$id], $type);

        return true;
    }

    /**
     * 更新用户 关系研究所报告 数据
     * @param int $id
     * @param int $uid
     * @param int $type 报告类型 1=>怎么追求Ta  2=>鉴“渣”神器
     * @param int $rid1
     * @param int $rid2
     * @param array $data
     * @return bool
     * @throws \Exception
     */
    public function UpdateData(int $id, int $uid, int $type, int $rid1, int $rid2, array $data)
    {
        try
        {
            $this->where(['id' => $id])->update($data);
        }
        catch (\Exception $e)
        {
            Log::write("ID【{$id}】更新 关系研究所报告 Zl1RelationAnalysisReport 数据失败：" . $e->getMessage() . '[ ' . $e->getFile() . '：' . $e->getLine() . ' ]', 'error', true);
            return false;
        }
        // 删除 详情
        $key = "{$uid}:{$rid1}:{$rid2}:{$type}";
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $key)->rmCache();
        // 删除列表详情
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $id)->rmCache();
        return true;
    }

    /**
     * 关系研究所报告 入队加 数据写入
     * @param int $uid
     * @param int $type 报告类型 1=>怎么追求Ta  2=>鉴“渣”神器
     * @param int $gid 解锁商品
     * @param string $order_id
     * @param int $rid1
     * @param int $rid2
     * @throws \app\common\lib\exception\ApiException
     */
    public function SaveAndQueue(int $uid, int $type, int $gid, string $order_id, int $rid1, int $rid2 = 0)
    {
        try
        {
            $now_time = time();
            $rids = [$rid1, $rid2];
            $rids = array_filter($rids);
            $recodeInfos = (new Recode())->batchGetInfoByIds($rids, ['id', 'name', 'type', 'year', 'month', 'day', 'hour', 'minute', 'timezone', 'birth_country', 'birth_province', 'birth_city', 'live_country', 'live_province', 'live_city', 'comments', 'isself', 'long_deg', 'long_min', 'ew', 'lat_deg', 'lat_min', 'ns', 'avatar', 'is_summer', 'uid', 'sun', 'moon', 'asc',]);

            foreach ($recodeInfos as $rid => $recodeInfoItem)
            {
                $utilModel = new Util();
                $recodeInfos[$rid]['sun'] = mb_substr($utilModel->recodeAstro($recodeInfoItem['sun']), 0, 2);
                $recodeInfos[$rid]['moon'] = mb_substr($utilModel->recodeAstro($recodeInfoItem['moon']), 0, 2);
                $recodeInfos[$rid]['asc'] = mb_substr($utilModel->recodeAstro($recodeInfoItem['asc']), 0, 2);
            }

            $recodeDatas = [
                'recode1' => $recodeInfos[$rid1],
                'recode2' => $recodeInfos[$rid2] ?? null,
            ];

            $recodesStr = \GuzzleHttp\json_encode($recodeDatas, JSON_UNESCAPED_UNICODE);

            $array = [
                'uid' => $uid,
                'rid1' => $rid1,
                'rid2' => $rid2,
                'type' => $type,
                'gid' => $gid,
                'order_num' => $order_id,
                'status' => 1,
                'recode_info' => $recodesStr,
                'create_time' => $now_time,
            ];
            $id = $this->insertGetId($array);
            // 删除详情缓存
            $key = "{$uid}:{$rid1}:{$rid2}";
            CacheManage::getInstance()->setCacheConfig($this->cacheModel, $key)->rmCache();
            //删除档案解锁的 报告 订单编号缓存
            CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('report_order_ids', "{$uid}:{$rid1}")->rmCache('report_order_ids');
            if ($rid2)
            {        //删除档案解锁的 报告 订单编号缓存
                CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('report_order_ids', "{$uid}:{$rid2}")->rmCache('report_order_ids');
            }
            // 添加小红点
            CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('is_new_report', "{$uid}:{$type}")->rmCache('is_new_report');
            // 列表添加
            $this->listDataAdd("{$uid}", [$id => $id], $type);
            if (Util::getVips($uid, $type === 1 ? 25 : 26, 0))
            {
                $queueDelay = 0;
            } else
            {
                $queueDelay = Env::get('host.name') === 'online' ? 150 : 10;
            }
            //关系研究所报告 入队
            Util::queuePush('relation_analysis_report', [
                'id' => $id,
                'uid' => $uid,
                'rid1' => $rid1,
                'rid2' => $rid2,
                'type' => $type,    // 报告类型 1=>怎么追求Ta  2=>鉴“渣”神器
                'gid' => $gid,
                'recodes' => $recodeDatas,
                'order_id' => $order_id,
                'push_switch' => true // 是否发送消息与推送
            ], $queueDelay ?? null);
        }
        catch (\Exception $e)
        {
            Log::write('Zl1RelationAnalysisReport model => SaveAndQueue()异常：' . $e->getMessage() . '失败行数：' . $e->getLine(), 'error');
        }
    }

    /**
     * 获取档案解锁的 怎么追求Ta 和 鉴"渣"申请 订单编号
     * @param int $uid
     * @param int $rid
     * @return array|mixed
     * @throws \Exception
     */
    public function getRecodeRelationAnalysisReportOrderIds(int $uid, int $rid)
    {
        return CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('report_order_ids', "{$uid}:{$rid}")->ZsGetIocData('report_order_ids', function () use ($uid, $rid)
        {
            try
            {
                $orderIds = $this->where(['uid' => $uid])->where(function ($query) use ($rid)
                {
                    $query->whereOr(['rid1' => $rid, 'rid2' => $rid]);
                })->column('order_num', 'order_num');

                return array_flip_key_value($orderIds);
            }
            catch (Exception $e)
            {
                return [];
            }
        });
    }

    /**
     * 获取订单备份档案信息
     * @param string $order_id
     * @return array|bool|mixed|string
     * @throws \Exception
     */
    public function getOrderRecodeBackRecode($order_id)
    {
        return CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('details_back_recode', $order_id)->getDataAndSet(function () use ($order_id)
        {
            try
            {
                return $this
                    ->where(['order_num' => $order_id])
                    ->group('order_num')
                    ->column('recode_info', 'id');
            }
            catch (\Exception $e)
            {
                return [];
            }
        }, [], 'details_back_recode');
    }

    /**
     * 获取档案当前状态解锁 关系研究所报告
     * @param int $uid
     * @param int $type 报告类型 1=>怎么追求Ta  2=>鉴“渣”神器
     * @param int $rid1
     * @param int $rid2
     * @return array
     * @throws \Exception
     */
    public function getUnlockGids(int $uid, int $type, int $rid1, int $rid2 = 0): array
    {
        $rids = [$rid1, $rid2];
        $rids = array_filter($rids);
        $recodes = (new \app\common\cachemodel\Recode())->batchGetInfoByIds($rids);

        $arr = [
            'msg' => '',
            'gids' => []
        ];
        $relationAnalysisReportData = $this->getRelationAnalysisReport($uid, 0, $type, $recodes[$rid1], $recodes[$rid2] ?? []);
        if (!$relationAnalysisReportData)
        {
            return $arr;
        }
        $goods = (new Goods())->batchGetInfoByIds($relationAnalysisReportData['gid']);

        if (!$relationAnalysisReportData['recode_is_change'])
        {
            $arr['msg'] = $goods[$relationAnalysisReportData['gid']]['name'] . '已购买';
            $arr['gids'][] = $relationAnalysisReportData['gid'];
        }

        return $arr;
    }

    /**
     * 获取用户档案解锁 关系研究所报告 详情
     * @param int $uid
     * @param int $id
     * @param int $type 报告类型 1=>怎么追求Ta  2=>鉴“渣”神器
     * @param array $recode1
     * @param array $recode2
     * @return array
     * @throws \Exception
     */
    public function getRelationAnalysisReport(int $uid, int $id, int $type, array $recode1, array $recode2 = [])
    {
        $recodeUniqueKey = "{$recode1['year']}:{$recode1['month']}:{$recode1['day']}:{$recode1['hour']}:{$recode1['minute']}:{$recode1['timezone']}:{$recode1['ew']}:{$recode1['long_deg']}:{$recode1['long_min']}:{$recode1['ns']}:{$recode1['lat_deg']}:{$recode1['lat_min']}:{$recode1['is_summer']}";
        if ($type === 1)
        {
            $recodeUniqueKey .= "|{$recode2['year']}:{$recode2['month']}:{$recode2['day']}:{$recode2['hour']}:{$recode2['minute']}:{$recode2['timezone']}:{$recode2['ew']}:{$recode2['long_deg']}:{$recode2['long_min']}:{$recode2['ns']}:{$recode2['lat_deg']}:{$recode2['lat_min']}:{$recode2['is_summer']}";
        }

        $relationAnalysisReportData = $this->getReportALL($uid, (int)$recode1['id'], (int)($recode2['id'] ?? 0), $type);

        if ($id)
        {
            $reportData = [];
            foreach ($relationAnalysisReportData as $key => $relationAnalysisReportDetailsItem)
            {
                $relationAnalysisReportDetailsItem['id'] = (int)$relationAnalysisReportDetailsItem['id'];
                if ($relationAnalysisReportDetailsItem['id'] === $id)
                {
                    if ($key === $recodeUniqueKey)
                    {
                        $relationAnalysisReportDetailsItem['recode_is_change'] = false;     // 档案未更新
                        $relationAnalysisReportDetailsItem['new_is_unlock'] = true;         // 已解锁最新
                        $relationAnalysisReportDetailsItem['new_history_id'] = $relationAnalysisReportDetailsItem['id'];         // 已解锁最新
                    } else
                    {
                        $relationAnalysisReportDetailsItem['recode_is_change'] = true;     // 档案未更新
                        if (isset($relationAnalysisReportData[$recodeUniqueKey]))
                        {
                            $relationAnalysisReportDetailsItem['new_is_unlock'] = true;     // 已解锁最新
                            $relationAnalysisReportDetailsItem['new_history_id'] = (int)$relationAnalysisReportData[$recodeUniqueKey]['id']; // 已解锁最新
                        } else
                        {
                            $relationAnalysisReportDetailsItem['new_is_unlock'] = false;    // 未解锁最新
                            $relationAnalysisReportDetailsItem['new_history_id'] = 0;       // 已解锁最新
                        }
                    }

                    $reportData = $relationAnalysisReportDetailsItem;
                }
            }
        } else
        {
            $reportData = [];
            if (isset($relationAnalysisReportData[$recodeUniqueKey]))
            {
                $relationAnalysisReportData[$recodeUniqueKey]['recode_is_change'] = false;
                $relationAnalysisReportData[$recodeUniqueKey]['new_is_unlock'] = true;  // 已解锁最新
                $reportData = $relationAnalysisReportData[$recodeUniqueKey];
            }
        }

        if (!$recode1['status'] || ($recode2 && !$recode2['status']))
        {
            $reportData['recode_is_change'] = false;
        }

        return $reportData;
    }

    /**
     * 判断 关系研究所 报告是否解锁
     * @param int $uid
     * @param int $type 报告类型 1=>怎么追求Ta  2=>鉴“渣”神器
     * @param int $rid1
     * @param int $rid2
     * @return array
     * @throws \Exception
     */
    public function getRelationAnalysisReportIsUnlock(int $uid, int $type, int $rid1, int $rid2 = 0): array
    {
        $relationAnalysisReportData = $this->getOrderRelationAnalysisReport($uid, $rid1, $rid2, $type);

        if ($relationAnalysisReportData)
        {
            $resData = [
                'is_unlock' => true,
                'id' => (int)$relationAnalysisReportData['id']
            ];
        } else
        {
            $resData = [
                'is_unlock' => false,
                'id' => 0
            ];
        }

        return $resData;
    }

    /**
     * 通过 订单查看历史
     * @param $uid
     * @param int $rid1
     * @param int $rid2
     * @param int $type 报告类型 1=>怎么追求Ta  2=>鉴“渣”神器
     * @param string $orderId
     * @return array
     * @throws \Exception
     */
    public function getOrderRelationAnalysisReport($uid, int $rid1, int $rid2, int $type, string $orderId = '')
    {
        $relationAnalysisReportData = $this->getReportALL($uid, $rid1, $rid2, $type);

        $resData = [];
        foreach ($relationAnalysisReportData as $key => $relationAnalysisReportDetailsItem)
        {
            $relationAnalysisReportDetailsItem['recode_is_change'] = false;   // 通过订单查看历史 默认档案未更新
            $relationAnalysisReportDetailsItem['new_is_unlock'] = true;   // 通过订单查看历史 默认已解锁最新

            if ($orderId && $relationAnalysisReportDetailsItem['order_num'] === $orderId)
            {
                $resData = $relationAnalysisReportDetailsItem;
                break;
            }

            if (empty($resData))
            {
                $resData = $relationAnalysisReportDetailsItem;
            } else
            {
                if ($relationAnalysisReportDetailsItem['id'] > $resData['id'])
                {
                    $resData = $relationAnalysisReportDetailsItem;
                }
            }
        }

        return $resData;
    }

    /**
     * 获取用户档案解锁 关系研究所报告 详情
     * @param $uid
     * @param int $rid1
     * @param int $rid2
     * @param int $type 报告类型 1=>怎么追求Ta  2=>鉴“渣”神器
     * @param array $field
     * @return array|bool|mixed
     * @throws \Exception
     */
    public function getReportALL($uid, int $rid1, int $rid2, int $type, $field = [])
    {
        $key = $uid . ':' . $rid1 . ':' . $rid2 . ':' . $type;

        $data = CacheManage::getInstance()->setCacheConfig($this->cacheModel, $key)->getDataAndSet(function () use ($uid, $rid1, $rid2, $type)
        {
            return $this->getReportByDb($uid, $rid1, $rid2, $type);
        }, $field);

        if ($data && $field && is_string($data))
        {
            $data = [current($field) => json_decode($data, true)];
        } else
        {
            foreach ($data as $dataKey => $valueStr)
            {
                $data[$dataKey] = json_decode($valueStr, true);
            }
        }

        return $data;
    }

    /**
     * 通过数据库 获取用户 档案 计算的所有
     * @param $uid
     * @param int $rid1
     * @param int $rid2
     * @param int $type 报告类型 1=>怎么追求Ta  2=>鉴“渣”神器
     * @return array
     */
    protected function getReportByDb($uid, int $rid1, int $rid2, int $type): array
    {
        try
        {
            $data = $this->where(['uid' => $uid, 'type' => $type, 'rid1' => $rid1, 'rid2' => $rid2, 'is_del' => 0, 'status' => ['in', [1, 2, 3]]])->order('id asc')->column('gid,type,rid1,rid2,order_num,content,status,recode_info,start_time', 'id');

            $resData = [];
            foreach ($data as $key => $value)
            {
                $value['recode_info'] = json_decode($value['recode_info'], true);
                $recode1 = $value['recode_info']['recode1'];
                $recodeUniqueKey = "{$recode1['year']}:{$recode1['month']}:{$recode1['day']}:{$recode1['hour']}:{$recode1['minute']}:{$recode1['timezone']}:{$recode1['ew']}:{$recode1['long_deg']}:{$recode1['long_min']}:{$recode1['ns']}:{$recode1['lat_deg']}:{$recode1['lat_min']}:{$recode1['is_summer']}";
                if ($type === 1)
                {
                    $recode2 = $value['recode_info']['recode2'];
                    $recodeUniqueKey .= "|{$recode2['year']}:{$recode2['month']}:{$recode2['day']}:{$recode2['hour']}:{$recode2['minute']}:{$recode2['timezone']}:{$recode2['ew']}:{$recode2['long_deg']}:{$recode2['long_min']}:{$recode2['ns']}:{$recode2['lat_deg']}:{$recode2['lat_min']}:{$recode2['is_summer']}";
                }

                $value['content'] = json_decode($value['content'], true);

                $resData[$recodeUniqueKey] = json_encode($value, JSON_UNESCAPED_UNICODE);
            }
        }
        catch (Exception $e)
        {
            $resData = [];
        }

        return $resData;
    }

    /**
     * @param array $ids
     * @param array|null $type
     * @param string $sortType
     * @return array
     */
    public function getInfoByIdsInData($ids, $type, $sortType)
    {
        $field = 'uid,type,is_del,gid,rid1,rid2,order_num,content,start_time,status,create_time,update_time,recode_info';
        try
        {
            if ($ids)
            {
                $where = ['id' => ['in', $ids]];
            } else
            {
                $where = ['uid' => $type[0], 'type' => $type[1], 'is_del' => 0];
            }

            $data = $this
                ->field($field)
                ->where($where)
                ->column($field, 'id');
        }
        catch (\Exception $e)
        {
            $data = [];
        }
        return $data;
    }

    public function batchGetInfoByIds($cids, $field = [])
    {
        $resData = parent::batchGetInfoByIds($cids, $field);

        foreach ($resData as $id => $orderItemData)
        {
            $resData[$id] = arrayKeyData2int($orderItemData, ['id', 'uid', 'is_del', 'type', 'status', 'gid', 'rid1', 'rid2', 'start_time', 'create_time', 'update_time']);

            if (isset($orderItemData['content']) && $orderItemData['content'])
            {
                $resData[$id]['content'] = json_decode($orderItemData['content'], true);
            }

            if (isset($orderItemData['recode_info']) && $orderItemData['recode_info'])
            {
                $resData[$id]['recode_info'] = json_decode($orderItemData['recode_info'], true);
            }
        }

        return $resData;
    }

    /**
     * 获取是否有小红点
     * @param int $uid
     * @param int $type 报告类型 1=>怎么追求Ta  2=>鉴“渣”神器
     * @return bool
     * @throws \Exception
     */
    public function getReportIsNew(int $uid, int $type)
    {
        $num = CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('is_new_report', "{$uid}:{$type}")
            ->getDataAndSet(function () use ($uid, $type)
            {
                try
                {
                    $num = $this->where(['uid' => $uid, 'type' => $type, 'is_del' => 0, 'is_read' => 0])->count();
                    return ['num' => $num];
                }
                catch (\Exception $e)
                {
                    Log::write('Zl1RelationAnalysisReport model => getReportIsNew()异常：' . $e->getMessage() . '失败行数：' . $e->getLine(), 'error');
                    return ['num' => 0];
                }
            }, [], 'is_new_report');

        return $num && $num['num'] > 0 ? true : false;
    }

    /**
     * 关系研究所【怎么追求Ta ｜ 鉴“渣”神器】报告已读
     * @param int $uid
     * @param int $id
     * @param int $type 报告类型 1=>怎么追求Ta  2=>鉴“渣”神器
     * @param int $rid1
     * @param int $rid2
     * @return bool
     */
    public function reportRead(int $uid, int $id, int $type, int $rid1, int $rid2 = 0)
    {
        try
        {
            $this->UpdateData($id, $uid, $type, $rid1, $rid2, ['is_read' => 1]);
            // 删除 小红点 缓存
            CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('is_new_report', "{$uid}:{$type}")->rmCache('is_new_report');
            return true;
        }
        catch (\Exception $e)
        {
            Log::write('Zl1RelationAnalysisReport model => reportRead()异常：' . $e->getMessage() . '失败行数：' . $e->getLine(), 'error');
            return false;
        }
    }
}
